package com.tpv.tv.pdf

import android.Manifest
import android.content.Context
import android.content.ContextWrapper
import android.content.Intent
import android.content.pm.ActivityInfo
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.util.Log
import android.view.View
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.gestures.detectTapGestures
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.RectangleShape
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.lifecycle.lifecycleScope
import androidx.tv.material3.Button
import androidx.tv.material3.Surface
import androidx.tv.material3.Text
import com.itextpdf.text.pdf.PdfEncryptor
import com.itextpdf.text.pdf.PdfReader
import com.itextpdf.text.pdf.PdfWriter
import com.tpv.app.pdf.TPVPDFUtil
import com.tpv.tv.lib.pdf.DocumentActivity
import com.tpv.tv.lib.pdf.PdfApi
import com.tpv.tv.pdf.common.RC_FILE_PICKER_PERM
import com.tpv.tv.pdf.ui.theme.MuPdfDemoTheme
import droidninja.filepicker.FilePickerBuilder
import droidninja.filepicker.FilePickerConst
import droidninja.filepicker.FilePickerConst.KEY_SELECTED_DOCS
import droidninja.filepicker.FilePickerConst.PERMISSIONS_FILE_PICKER
import droidninja.filepicker.models.sort.SortingTypes
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import me.rosuh.filepicker.adapter.FileListAdapter
import me.rosuh.filepicker.config.FileItemOnClickListener
import me.rosuh.filepicker.config.FilePickerManager
import pub.devrel.easypermissions.AfterPermissionGranted
import pub.devrel.easypermissions.AppSettingsDialog
import pub.devrel.easypermissions.EasyPermissions
import java.io.File
import java.io.FileOutputStream


class MainActivity : ComponentActivity(), EasyPermissions.PermissionCallbacks {
    private sealed class FileBusiness<out R> {
        data object OpenPdf : FileBusiness<Nothing>()
        data object OpenPdfSdk : FileBusiness<Nothing>()
        data object OpenEncryptPdf : FileBusiness<Nothing>()
        data object EncryptPdf : FileBusiness<Nothing>()
    }
    private val isOnTV = true
    private var currentBus = mutableStateOf<FileBusiness<Any>>(FileBusiness.OpenPdf)
    private val FILE_REQUEST = 42
    private val docPaths = arrayListOf<Uri>()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MuPdfDemoTheme {
                Column(modifier = Modifier.fillMaxSize(),
                    verticalArrangement = Arrangement.Center,
                    horizontalAlignment = Alignment.CenterHorizontally) {
                    Surface(
                        modifier = Modifier.pointerInput(Unit) {
                            detectTapGestures(
                                onTap = {
                                    currentBus.value = FileBusiness.OpenPdf
                                    pickDocClicked()
                                }
                            )
                        },
                        shape = RectangleShape
                    ) {
                        Button(onClick = {
                            currentBus.value = FileBusiness.OpenPdf
                            pickDocClicked()
                        }) {
                            Text(text = "测试Pfd展示")
                        }
                    }
                    Spacer(modifier = Modifier.height(20.dp))
                    Surface(
                        modifier = Modifier.pointerInput(Unit) {
                            detectTapGestures(
                                onTap = {
                                    currentBus.value = FileBusiness.OpenEncryptPdf
                                    pickDocClicked()
                                }
                            )
                        },
                        shape = RectangleShape
                    ) {
                        Button(onClick = {
                            currentBus.value = FileBusiness.OpenEncryptPdf
                            pickDocClicked()
                        }) {
                            Text(text = "测试Pfd加密展示")
                        }
                    }
                    Spacer(modifier = Modifier.height(20.dp))
                    Surface(
                        modifier = Modifier.pointerInput(Unit) {
                            detectTapGestures(
                                onTap = {
                                    currentBus.value = FileBusiness.EncryptPdf
                                    pickDocClicked()
                                }
                            )
                        },
                        shape = RectangleShape
                    ) {
                        Button(onClick = {
                            currentBus.value = FileBusiness.EncryptPdf
                            pickDocClicked()
                        }) {
                            Text(text = "测试Pfd加密")
                        }
                    }
                    Spacer(modifier = Modifier.height(20.dp))
                    Surface(
                        modifier = Modifier.pointerInput(Unit) {
                            detectTapGestures(
                                onTap = {
                                    currentBus.value = FileBusiness.OpenPdfSdk
                                    pickDocClicked()
                                }
                            )
                        },
                        shape = RectangleShape
                    ) {
                        Button(onClick = {
                            currentBus.value = FileBusiness.OpenPdfSdk
                            pickDocClicked()
                        }) {
                            Text(text = "测试Pfd跳转")
                        }
                    }
                }
            }
        }
    }

    private fun goShowNormalPdf() {
//        val path = "/storage/emulated/0/Download/6Sigma简介.pdf"
        val path = "/storage/emulated/0/Download/FW5_Issue.pdf"
        goShowPdf(path)
    }

    private fun goShowEncryptPdf() {
        val path = "/storage/emulated/0/Download/encrypt_6Sigma简介.pdf"
        goShowPdf(path)
    }

    private fun goShowOtherSidePdf() {
//        val path = "/storage/emulated/0/Download/6Sigma简介.pdf"
        val path = "/storage/emulated/0/Download/FW5_Issue.pdf"
        goShowPdf(path, true)
    }

    private fun goShowOtherSideEncryptPdf() {
        val path = "/storage/emulated/0/Download/encrypt_6Sigma简介.pdf"
        goShowPdf(path, true)
    }

    private fun goShowPdf(path: String, isOtherSide: Boolean = false) {
        if(isOtherSide) {
            val fakeContext = FakeContextWrapper(applicationContext)
            TPVPDFUtil.openPDFActivity(fakeContext, path)
        } else {
            PdfApi.openPdf(this, path)
        }
    }

    @AfterPermissionGranted(RC_FILE_PICKER_PERM)
    fun pickDocClicked() {
        val permissions = mutableListOf<String>()
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
            permissions += Manifest.permission.READ_MEDIA_IMAGES
            permissions += Manifest.permission.READ_MEDIA_VIDEO
            permissions += Manifest.permission.READ_MEDIA_VISUAL_USER_SELECTED
        } else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.TIRAMISU) {
            permissions += Manifest.permission.READ_MEDIA_IMAGES
            permissions += Manifest.permission.READ_MEDIA_VIDEO
        } else {
            permissions += PERMISSIONS_FILE_PICKER
        }
        permissions += Manifest.permission.WRITE_EXTERNAL_STORAGE
        if (EasyPermissions.hasPermissions(this, *permissions.toTypedArray())) {
//            onPickDoc()
            if(isOnTV) {
                when(currentBus.value) {
                    is FileBusiness.OpenPdf -> {
                        goShowNormalPdf()
                    }
                    is FileBusiness.OpenEncryptPdf -> {
                        goShowEncryptPdf()
                    }
                    is FileBusiness.OpenPdfSdk -> {
                        goShowOtherSidePdf()
                    }else -> {}
                }
            } else {
                openFilePic()
            }
        } else {
            // Ask for one permission
            EasyPermissions.requestPermissions(this, getString(R.string.rationale_doc_picker),
                RC_FILE_PICKER_PERM, *permissions.toTypedArray())
        }
    }

    private fun openFilePic() {
        FilePickerManager
                   .from(this@MainActivity)
            .setItemClickListener(object: FileItemOnClickListener {
                override fun onItemChildClick(itemAdapter: FileListAdapter,
                    itemView: View,
                    position: Int) {
                    val data = itemAdapter.dataList[position]
                    Log.d("zlq", "onItemChildClick fileName : ${data.fileName}, fileType : ${data.fileType?.fileType}")
                }

                override fun onItemClick(itemAdapter: FileListAdapter,
                    itemView: View,
                    position: Int) {
                    val data = itemAdapter.dataList[position]
                    Log.d("zlq", "onItemClick fileName : ${data.fileName}, fileType : ${data.fileType?.fileType}")
                }

                override fun onItemLongClick(itemAdapter: FileListAdapter,
                    itemView: View,
                    position: Int) {
                    val data = itemAdapter.dataList[position]
                    Log.d("zlq", "onItemLongClick fileName : ${data.fileName}, fileType : ${data.fileType?.fileType}")
                }
            })
            .enableSingleChoice()
            .forResult(FilePickerManager.REQUEST_CODE)
    }

    private fun onPickDoc() {
        FilePickerBuilder.instance
            .setMaxCount(1)
//            .setSelectedFiles(docPaths)
            .setActivityTitle("Please select doc")
            .setImageSizeLimit(5) //Provide Size in MB
            .setVideoSizeLimit(20) //                    .addFileSupport("ZIP", zips)
            //                    .addFileSupport("AAC", pdfs, R.drawable.pdf_blue)
            .enableDocSupport(true)
            .enableSelectAll(true)
            .sortDocumentsBy(SortingTypes.NAME)
            .withOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED)
            .pickFile(this)
    }

    @Deprecated("This method has been deprecated in favor of using the Activity Result API\n      which brings increased type safety via an {@link ActivityResultContract} and the prebuilt\n      contracts for common intents available in\n      {@link androidx.activity.result.contract.ActivityResultContracts}, provides hooks for\n      testing, and allow receiving results in separate, testable classes independent from your\n      activity. Use\n      {@link #registerForActivityResult(ActivityResultContract, ActivityResultCallback)}\n      with the appropriate {@link ActivityResultContract} and handling the result in the\n      {@link ActivityResultCallback#onActivityResult(Object) callback}.")
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == FILE_REQUEST && resultCode == RESULT_OK) {
            val intent = Intent(this, DocumentActivity::class.java)
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT)
            intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK)
            intent.setAction(Intent.ACTION_VIEW)
            intent.setDataAndType(data?.data, data?.type)
            intent.putExtra(componentName.packageName + ".ReturnToLibraryActivity", 1)
            startActivity(intent)
            if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.S_V2) finish()
        } else if (requestCode == FILE_REQUEST && resultCode == RESULT_CANCELED) {
            Toast.makeText(this, "取消", Toast.LENGTH_SHORT).apply {
                show()
            }
        } else if(requestCode == FilePickerConst.REQUEST_CODE_DOC && resultCode == RESULT_OK) {
            data?.let {
                val dataList: ArrayList<Uri> = it.getParcelableArrayListExtra(KEY_SELECTED_DOCS)!!
                val intent = Intent(this, DocumentActivity::class.java)
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT)
                intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK)
                intent.setAction(Intent.ACTION_VIEW)
                intent.setDataAndType(dataList[0], data.type)
                intent.putExtra(componentName.packageName + ".ReturnToLibraryActivity", 1)
                startActivity(intent)
            }
        } else if(requestCode == FilePickerManager.REQUEST_CODE && resultCode == RESULT_OK) {
            Log.d("zlq", "data : $data")
            val list = FilePickerManager.obtainData(release = true)
            Log.d("zlq", "list : $list")
            list[0].substringAfterLast('.', "").lowercase()
            when(currentBus.value) {
                is FileBusiness.OpenPdf -> {
                    PdfApi.openPdf(this, list[0])
                }
                is FileBusiness.OpenPdfSdk -> {
                    val fakeContext = FakeContextWrapper(applicationContext)
                    TPVPDFUtil.openPDFActivity(fakeContext, list[0])
                }
                is FileBusiness.OpenEncryptPdf -> {
                    PdfApi.openPdf(this, list[0])
                }
                is FileBusiness.EncryptPdf -> {
                    lifecycleScope.launch(Dispatchers.IO) {
                        try {
                            val password = "12344321"
                            val src = list[0]
                            val file = File(src)
                            if(file.exists().not()) {
                                withContext(Dispatchers.Main) {
                                    Toast.makeText(this@MainActivity, "文件不存在", Toast.LENGTH_SHORT).show()
                                }
                                return@launch
                            }
                            val pathWithoutFilename =
                                file.absolutePath.substring(0, file.absolutePath.lastIndexOf(
                                    File.separator))
                            val dest = pathWithoutFilename.plus(File.separator).plus("encrypt_" + file.name)
                            Log.d("zlq", "destPath : $dest")
                            // 创建 PdfReader 对象
                            val reader = PdfReader(src)
                            // 创建输出文件的 PdfWriter 对象
                            FileOutputStream(dest).use { fos ->
                                // 设置密码保护并加密 PDF
                                PdfEncryptor.encrypt(reader,
                                    fos,
                                    true,
                                    password,
                                    password,
                                    PdfWriter.ALLOW_PRINTING)
                            }
                            withContext(Dispatchers.Main) {
                                Toast.makeText(this@MainActivity, "pdf加密成功", Toast.LENGTH_SHORT).show()
                            }
                        } catch (e: Exception) {
                            e.printStackTrace()
                        }
                    }
                }
            }
        }
    }

    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>,
        grantResults: IntArray) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)

        EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this)
    }

    override fun onPermissionsGranted(requestCode: Int, perms: List<String?>) {
    }

    override fun onPermissionsDenied(requestCode: Int, perms: List<String?>) {
        if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) {
            AppSettingsDialog.Builder(this).build().show()
        }
    }
}

class FakeContextWrapper(base: Context) : ContextWrapper(base) {
    override fun getPackageName(): String {
        return "com.tpv.app.pdf.test" // 伪装成不同的包名
    }
}

@Preview(showBackground = true)
@Composable
fun GreetingPreview() {
    MuPdfDemoTheme {

    }
}